perm filename READ.MUS[MUS,LCS] blob sn#469436 filedate 1979-08-28 generic text, type T, neo UTF8
<     ****** READING IN AND PROCESSING EXTERNAL DIGITAL SOUND FILES *****
<
<     A special set of subroutines in the MUS10 program may be called to
<     read in as  many as  4 external sound  files simultaneously.   The
<     basic information for initializing this capability is found in the
<     file  'READ[MUS,LCS]'.  This  file,  which  contains  four  READIN
<     functions,  'READIN',   'READI2',   'READI3'  and   'READI4',   is
<     reproduced in full below.
<
<     The first lines are needed to declare the presence of some machine
<     language routines  which read  external files  from the  disk  and
<     unpack the samples in the proper manner.  The second set of  lines
<     set up  the necessary  arrays for  temporarily storing  the  sound
<     samples.  Then a group of variables are declared for  transferring
<     various kinds of information for each 'READIN' function.
<
<     SCNT, SCNT2, SCNT3 and SCNT4  are the overall sample counters  for
<     each 'READIN' unit.   They must  be set to  zero each  time it  is
<     desired to read from the beginning of a file.  After this  counter
<     exceeds the length of the file  then zeros will be sent back  from
<     the function.
<
<     CNT, CNT2, etc. are sample counters  which are used to keep  track
<     of when a new sample buffer must be read in.  The other  variables
<     carry the following information:
<
<        RD = the value of the current sample.
<        INCH = NCHNS of the file
<        INSR = SRATE of the file
<        INDR = duration of the file in samples
<        INBT = bits per sample   (0 = 12,  1 = 18)
<        INBUF = 1536 if 12-bit samples, 1024 if 18-bit samples.
<        INMX = maximum amplitude of file
<
<     Note that RD, CNT and SCNT must be 'run-time' variables because
<     their values must be read for every sample.
<
<     ********************************************************************
      EXTERNAL FUNCTION GETINF(ARRAY J,INSR,INBT,INCH,INMX,INDR),
      RDSMPL(ARRAY N,BITS),GETIN2(ARRAY J,INSR,INBT,INCH,INMX,INDR),
      RDSMP2(ARRAY N,BITS),GETIN3(ARRAY J,INSR,INBT,INCH,INMX,INDR),
      RDSMP3(ARRAY N,BITS),GETIN4(ARRAY J,INSR,INBT,INCH,INMX,INDR),
      RDSMP4(ARRAY N,BITS);
 
      ARRAY INF, IN2, IN3, IN4(1536);
      VARIABLE /CNT,/RD,/SCNT,INCH,INSR,INMX,INDR,INBT,INBUF,
      /CNT2,/RD2,/SCNT2,INBT2,INBUF2, INDR2,INDR3,INDR4,
      /CNT3,/RD3,/SCNT3,INDR3,INBT3,INBUF3,
      /CNT4,/RD4,/SCNT4,INDR4,INBT4,INBUF4;
 
      FUNCTION PRNTIT(CNT,INBT,INDR,INBUF);  
      BEGIN  VARIABLE DUR;  <***** don't forget to init. SCNT←0; ****
        INBUF←1535-512*INBT;  DUR←INDR/INSR/INCH;
        PRINT "SRATE=",INSR," BITS=",12+INBT*6," NCHNS=",INCH,
        " MAXAMP=",INMX," DUR=",DUR;
        CNT←2000;     < ANY NUMBER > 1536
      END;

      FUNCTION READIN(RD);
      BEGIN 		<***** DON'T FORGET TO INIT SCNT ← 0;
        IF SCNT=0 THEN BEGIN  <****** READ HEADER INTO ARRAY INF.
        PRINT "****READING ",INFILE,".SND****";
          GETINF(INF,INSR,INBT,INCH,INMX,INDR);
          PRNTIT(CNT,INBT,INDR,INBUF);
        END;
      SCNT←SCNT+1;  < ***** UPDATE THE COUNTER
      IF SCNT > INDR THEN  BEGIN <***CHECK IF SMPL CNT IS EXCEEDED
        RD←0;  RETURN(RD); END;
      IF CNT > INBUF THEN BEGIN
        RDSMPL(INF,INBT);   <**** GET A NEW BUFFER WHEN NECESSARY
        CNT←0;  END;
      RD←INF(CNT);  <**** PUT VALUE OF SAMPLE INTO RD
      CNT←CNT+1; <**** UPDATE THE COUNTER
      RETURN(RD); END;   <**** VALUE OF RD IS RETURNED IN READIN(RD)

      FUNCTION READI2(RD2);  < ***** DUPLICATE OF 'READIN' *****
      BEGIN 
        IF SCNT2=0 THEN BEGIN  
          PRINT "****READING ",INFIL2,".SND****";
          GETIN2(IN2,INSR,INBT2,INCH,INMX,INDR2); 
          PRNTIT(CNT2,INBT2,INDR2,INBUF2);
        END;
      SCNT2←SCNT2+1;
      IF SCNT2 > INDR2 THEN  BEGIN 
        RD2←0;  RETURN(RD2); END;
      IF CNT2 > INBUF2 THEN BEGIN
        RDSMP2(IN2,INBT2);
        CNT2←0;  END;
      RD2←IN2(CNT2); 
      CNT2←CNT2+1; 
      RETURN(RD2); END; 

      FUNCTION READI3(RD3);
      BEGIN 		
        IF SCNT3=0 THEN BEGIN  
          PRINT "****READING ",INFIL3,".SND****";
          GETIN3(IN3,INSR,INBT3,INCH,INMX,INDR3); 
          PRNTIT(CNT3,INBT3,INDR3,INBUF3);
        END;
      SCNT3←SCNT3+1;
      IF SCNT3 > INDR3 THEN  BEGIN 
        RD3←0;  RETURN(RD3); END;
      IF CNT3 > INBUF3 THEN BEGIN
        RDSMP3(IN3,INBT3);
        CNT3←0;  END;
      RD3←IN3(CNT3);
      CNT3←CNT3+1; 
      RETURN(RD3); END; 

      FUNCTION READI4(RD4);
      BEGIN 		
        IF SCNT4=0 THEN BEGIN  
          PRINT "****READING ",INFIL4,".SND****";
          GETIN4(IN4,INSR,INBT4,INCH,INMX,INDR4); 
          PRNTIT(CNT4,INBT4,INDR4,INBUF4);
        END;
      SCNT4←SCNT4+1;
      IF SCNT4 > INDR4 THEN  BEGIN 
        RD4←0;  RETURN(RD4); END;
      IF CNT4 > INBUF4 THEN BEGIN
        RDSMP4(IN4,INBT4);
        CNT4←0;  END;
      RD4←IN4(CNT4);
      CNT4←CNT4+1; 
      RETURN(RD4); END; 
<   ***********************************************************
<
<     The file 'READ' also contains the following possible READIN 
<     instruments.   These instruments simply put some over-all 
<     amplitude envelope on the sound which is read in.
<     The names of the files to be read in will be in INFILE for
<     FUNCTION READIN, in INFIL2 for FUNCTION READI2, in INFIL3
<     for READI3, and in INFIL4 for READI4.  !!!!! ONLY 5 LETTERS
<     MAY BE USED FOR INPUT FILE NAMES AND THE EXTENSION SHOULD
<     NOT BE USED (.SND IS ASSUMED.)!!!  Examples of how to set
<     the input file names is found in the play list below the
<     instrument definitions.
<
<   ************************************************************

      SEG(F6);0 0 .7 20  .5 50  1 80  0 100; <ENVELOPE ON INPUT SOUND.
      INSTRUMENT READA;	<**** A POSSIBLE READIN INSTRUMENT.
      OSCIL(P4,MAG/P2,F6);
      OUTA←OUTA+U1*READIN(RD);
      END;
      INSTRUMENT READB;
      OSCIL(P4,MAG/P2,F6);
      OUTA←OUTA+U1*READI2(RD2);
      END;
      INSTRUMENT READC;
      OSCIL(P4,MAG/P2,F6);
      OUTA←OUTA+U1*READI3(RD3);
      END;
      INSTRUMENT READD;
      OSCIL(P4,MAG/P2,F6);
      OUTA←OUTA+U1*READI4(RD4);
      END;

<     OUTFILE←"RD.SND";  <**** the extension must appear here.
<     PLAY; 
<     READA 0  .37  0 2; <*** amplitude will be doubled
<     INFILE←"U";  <FILE NAME TO BE READ IN FOR NOTE ABOVE THIS LINE!!!
<     SCNT←0; 	<initialize counter file above.
<     READB .3  .37  0 1; <**** amplitude will be unchanged
<     INFIL2←"A";   <FILE NAME TO BE READ IN. (.SND extension assumed.)
<     SCNT2←0;       < intitialize the counter
<     READC .8 .37  0 .7;  <**** note the amplitude
<     INFIL3←"I";        <FILE NAME TO BE READ IN.
<     SCNT3←0;
<     READA 1.3 .37  0  .8;  SCNT←0; <*** use READA again
<     INFILE←"U"; <FILE NAME TO BE READ IN FOR NOTE ABOVE THIS LINE!!!
<     FINI;
<
<   ********************************************************************
<
<     Just before the above play list the output file name has been  set
<     'RD.SND'.  (When the  output file  name is  changed the  extension
<     must!! be given.)  Within the play list the mention of each READIN
<     instrument is immediately  followed!! by the  input file name  and
<     the initialization  of the  main sample  counter for  that  READIN
<     function.
<
<     The names of the  input files must have  the extension '.SND'  but
<     the extensions should not  be typed here.   Parameter 2 tells  how
<     long the READIN instrument is to be turned on.  Normally P2  would
<     be set to at  least the duration  of the file  being read in.   In
<     these instruments P4 can be used to scale the original amplitudes.
<
<     Many different sorts of instruments may be designed to make use of
<     the READIN  functions.   For example  mono  input samples  may  be
<     processed into stereo output, the  samples may be reverberated  or
<     the samples may be amplitude-modulated in many ways.
<
<
<    ******** VARIABLE INCREMENT RATES IN READA **********************
<
<     The following variant of the  READIN function allows you to  alter
<     the increment, or reading rate, of  the input file.  This has  the
<     effect of dynamically altering the sample rate of the input sound.
<     To avoid rough edges, an  interpolation section has been added  to
<     the READIN function.
<
<    ******************************************************************
<
<     EXTERNAL FUNCTION GETINF(ARRAY J,INSR,INBT,INCH,INMX,INDR),
<     RDSMPL(ARRAY N,BITS);
<
<     ARRAY INF(1536);
<     VARIABLE /CNT,/RD,/SCNT,INCH,INSR,INMX,INDR,INBT,INBUF,
<     IX,/INC,RX,JZ,IZ;
<
<     FUNCTION PRNTIT(CNT,INBT,INDR,INBUF);  
<     BEGIN 
<       INBUF←1536-512*INBT ; << THIS WAS ORIGINALLY 1535, BUT MAYBE WAS WRONG?
<       PRINT "SRATE=",INSR," BITS=",12+INBT*6," NCHNS=",INCH,
<       " MAXAMP=",INMX," DUR=",INDR/INSR/INCH;
<           INDR←INDR-2;
<     END;
<
<     FUNCTION READIN(RD);
<     BEGIN 		<DON'T FORGET TO INIT AND SCNT ← 0;
<       IF SCNT=0 THEN BEGIN        
<         GETINF(INF,INSR,INBT,INCH,INMX,INDR); <HEADER IS READ INTO ARRAY INF.
<         PRNTIT(CNT,INBT,INDR,INBUF);
<          RDSMPL(INF,INBT);
<    	   CNT←0;  JZ←0; RX←INF(0);
<       END;
<       SCNT←SCNT+INC; 
<       IF SCNT > P6 THEN INC←INC+P5;<******SPECIAL FEATURE***************
<
<       IF SCNT > INDR THEN  BEGIN <CHECK TO SEE IF SMPL CNT IS EXCEEDED
<          RD←0;  RETURN(RD); END;
<        IX ← INF(JZ);
<        IZ←1-INT(JZ)+CNT;
<           RD←RX+(IX-RX)*IZ;   < INTERPOLATION
<       CNT←CNT+INC; <UPDATE THE COUNTER
<
<       IF CNT < INBUF THEN RX←INF(CNT);
<	JZ←CNT+1; 
<
<       IF JZ ≥ INBUF THEN BEGIN
<          RDSMPL(INF,INBT);
<          JZ←JZ-INBUF;  
<	   CNT←JZ-1;
<	   IF CNT ≥ 0 THEN RX←INF(CNT);
<      	    END;
<       RETURN(RD); 
<    END; 
<
<    ************************************************************                
<
<     INSTRUMENT READA;
<     OUTA←OUTA+P4*READIN(RD);
<     END;
<     
<     INC←1;  < MUST BE INITIALIZED.
<     PLAY;
<     READA  0  .37  0  1.3  .00025  1920;
<     SCNT←0; INFILE←"U"; 
<     FINISH;
<
<   ***************************************************************
<
<     In the above example P5  is used to cause  a slight change in  the
<     increment rate.  P6  is used (in  the function) to  tell when  the
<     increment rate will begin to change.   In the above case a  vowel,
<     "ou" (human voice), is processed  to have an upward inflection  at
<     the end.  The change  in the increment may  seem to be very  small
<     but after 12800 samples (or 1 second) the increment will be up  to
<     2.5.